﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using SchemaMonitor;
using F = Framework;
using SchemaMonitor.json;

public partial class usercontrols_UCNode : System.Web.UI.UserControl
{
	public void Display(CNode node)
	{
		if (Parent.Controls.Count % 2 == 0)
			row.Attributes.Add("class", "alt_row");

		string t = node.Type.TypeName;
		if (t.Length == 0)
			foreach (var i in node.Type.Signatures)
				if (t.Length == 0 || i.SigDescription.Length < t.Length)
					t = i.SigDescription;
		lblType.Text = t;

		lblDate.Text = F.CUtilities.Timespan(node.NodeCreated);
		lblDate.ToolTip = F.CUtilities.LongDateTime(node.NodeCreated);

		var r = node.Root;
		lnkName.Text = r.Name;
		lnkName.ToolTip = string.Concat(r.Id, "\r\n", r.IdBase64);

		//lnkName.NavigateUrl = string.Concat("http://www.facebook.com/profile.php?id=", u.UserId);
	}
	public void Display(CUser user)
	{
		if (Parent.Controls.Count % 2 == 0)
			row.Attributes.Add("class", "alt_row");

		lblType.Text = "User";

		lblDate.Text = F.CUtilities.Timespan(user.UserCreated);
		lblDate.ToolTip = F.CUtilities.LongDateTime(user.UserCreated);

		lnkName.Text = user.UserName;
		lnkName.ToolTip = user.UserId.ToString();
		//lnkName.NavigateUrl = string.Concat("http://www.facebook.com/profile.php?id=", u.UserId);
	}
	public void Display(CChange c)
	{
		Display(c.Node);

		lnkName.Visible = false;
		tbl.Visible = true;
		tbl.Width = new Unit("300");
		foreach (var i in c.Diff)
		{
			var tr = AddRow(tbl);
			AddCell(tr, i.Path);
			AddCell(tr, null == i.Before ? string.Empty : i.Before.AsString);
			AddCell(tr, i.After.AsString);
		}
	}
	public void DisplayAll(CNode node, int number, CUser u)
	{
		if (Parent.Controls.Count % 2 == 0)
			row.Attributes.Add("class", "alt_row");

		lblType.Text = "#" + number + ". ";//node.Root.Name;
										   //lblType.ToolTip = string.Concat(node.Type.TypeName, ": ", node.NodeId);

		//lblDate.Text = F.CUtilities.Timespan(node.NodeCreated);
		//lblDate.ToolTip = F.CUtilities.LongDateTime(node.NodeCreated);
		colDate.Visible = false;
		colTable.ColSpan = 2;

		lnkName.Visible = false;
		tbl.Visible = true;
		tbl.CellPadding = 0;
		tbl.CellSpacing = 0;

		var r = node.Root;

		var orderFirst = new List<string>()
		{
			"name", "count","link", "id",  "cover_photo", "type", "privacy"
		};
		var orderLast = new List<string>()
		{
			"created_time", "updated_time", "created"
		};


		foreach (var i in orderFirst)
			if (r.Fields.Has(i))
				AddRow(tbl, r.Fields[i], u);

		foreach (var i in r.Fields)
			if (null != i.Tag)
				if (!orderFirst.Contains(i.Tag.TagName)
				  && !orderLast.Contains(i.Tag.TagName))
				AddRow(tbl, i, u);

		foreach (var i in orderLast)
			if (r.Fields.Has(i))
				AddRow(tbl, r.Fields[i], u);

		//var f = CField.Factory("created", node.NodeCreated, r, temp);
		//AddRow(tbl, f, u);
	}

	private TableRow AddRow_Coll(Table tbl, CField f, ref string prefix, out bool highlight)
	{
		//Hightlight name row
		highlight = "name" == f.Tag.TagName;
		var tr = AddRow(tbl, highlight);

		//Path (or TagName)
		if (prefix.Length == 0)
			prefix = f.Tag.TagName;
		else
			prefix = string.Concat(prefix, ".", f.Tag.TagName);

		//TagName
		var td1 = AddCell(tr, prefix).Font.Bold = true;
		return tr;
	}


	private void AddRow(Table tbl, CField f, CUser u, string prefix = "")
    {
		bool highlight = false;
		var tr = AddRow_Coll(tbl, f, ref prefix, out highlight);

		//Fixup
		var t = f.Tag.FieldType;
		if (f is CFieldPointer)
		{
			if (f.Tag.TagIsList)
				try
				{
					var x = f.AsPointerList(u.All);
				}
				catch
				{
					var x = f.AsCompositeList;
					f = new CFieldComposite(f.Parent, f.Tag, f.AsCompositeList.ToArray(), u);
				}
			else
				try
				{
					var x = f.AsPointer(u.All);
				}
				catch
				{
					var x = f.AsComposite;
					f = new CFieldComposite(f.Parent, f.Tag, f.AsComposite);
				}
		}
		if (f is CFieldComposite)
		{
			if (f.Tag.TagIsList)
				try
				{
					var x = f.AsCompositeList;
				}
				catch
				{
					var x = f.AsPointerList(u.All);
					f = new CFieldPointer(f.Parent, f.Tag, f.AsPointerList(u.All));
				}
			else
				try
				{
					var x = f.AsComposite;
				}
				catch
				{
					var x = f.AsPointer(u.All);
					f = new CFieldPointer(f.Parent, f.Tag, f.AsPointer(u.All));
				}
		}


		List<CNodeBasic> moreRows = null;


		//Value
		if (f is CFieldPointer)
			moreRows = AddCell_Reference(tr, (CFieldPointer)f, u);
		else if (f is CFieldComposite)
			moreRows = AddCell_Composite(tr, (CFieldComposite)f);
		else if (t.IsSystem)
		{
			var td = AddCell_System(tr, f, highlight);

			if ("link" == f.Tag.TagName || td.Text.StartsWith("http"))
				SetLink(td);
        }


		//Last Row: Type
		AddCell(tr, t.TypeName).Font.Italic = true;// string.Concat("[", prefix, "]"));


		//More rows
		if (null != moreRows)
			foreach (var i in moreRows)
				foreach (var j in i.Fields)
					AddRow(tbl, j, u, prefix);
	}
	private void SetLink(TableCell td)
	{
		string url = td.ToolTip;
		if (url.Length == 0)
			url = td.Text;
		SetLink(td, url);
	}
	private void SetLink(TableCell td, string url)
	{
		var lnk = new HyperLink();
		lnk.Text = td.Text;
		lnk.ToolTip = td.ToolTip;
		lnk.NavigateUrl = url;
		td.Text = string.Empty;
		td.Controls.Add(lnk);
	}
	private List<CNodeBasic> AddCell_Reference(TableRow tr, CFieldPointer f, CUser u)
	{
		CTag t = f.Tag;
		if (t.TagIsList)
			return AddCell_ReferenceList(tr, f, u);
		else
			return AddCell_ReferenceItem(tr, f, u);
	}
	private List<CNodeBasic> AddCell_ReferenceItem(TableRow tr, CFieldPointer f, CUser u)
	{
		var node = f.AsPointer(u.All);
		var r = node.Root;
		var t = f.Tag;
		var td = AddCell(tr, t.TagName + " #"  + r.Id);


		if (t.FieldType.TypeName == "user")
		{
			var su = new CSoftUser(node.Root, u);
			td.Text = su.Name;
			td.Font.Bold = true;
			return new List<CNodeBasic>(0);
		}

		return new List<CNodeBasic>() { node.Root };
	}
	private List<CNodeBasic> AddCell_ReferenceList(TableRow tr, CFieldPointer f, CUser u)
	{
		var ptrs = f.AsPointerList(u.All);

		var roots = new List<CNodeBasic>();
		foreach (var i in ptrs)
			roots.Add(i.Root);

		if (f.Tag.TagName == "likes")
		{
			var names = new List<string>(roots.Count);
			foreach (var i in roots)
				names.Add(new CSoftUser((CNodeRoot)i,u).Name);
			AddCell(tr, names);
			return new List<CNodeBasic>(0);
		}
		if (f.Tag.TagName == "comments")
		{
			var names = new List<string>(roots.Count);
			foreach (var i in roots)
			{
				var name = i.Name;
				try
				{
					var from = i.Fields["from"];
					var usr = f.AsPointer(u.All).Root;
					var soft = new CSoftUser(usr, u);
					name = soft.Name;
				}
				catch { }

				var count = i.Fields["like_count"].AsLong;
				var msg = i.Fields["message"].AsString;
				var s = F.CUtilities.NameAndCount(name, (int)count.Value);
				s = string.Concat("<b>" , s, "</b>: ", msg);
				names.Add(s);
			}
			AddCell(tr, names);
			return new List<CNodeBasic>(0);
		}



		if (ptrs.Count == 1)
			return AddCell_ReferenceItem(tr, f, u);


		AddCell(tr, F.CUtilities.NameAndCount(f.Tag.TagName, roots));
		return roots;
	}
	private List<CNodeBasic> AddCell_Composite(TableRow tr, CFieldComposite f)
	{
		CTag t = f.Tag;
		if (t.TagIsList)
			return AddCell_CompositeList(tr, f);
		else
			return AddCell_CompositeItem(tr, f);
	}
	private List<CNodeBasic> AddCell_CompositeItem(TableRow tr, CFieldComposite f)
	{
		var node = f.AsComposite;
		AddCell(tr, f.Tag.TagName);
		return new List<CNodeBasic>() { node };
	}
	private List<CNodeBasic> AddCell_CompositeList(TableRow tr, CFieldComposite f)
	{
		var list = f.AsCompositeList;

		if (f.Tag.TagName == "images")
		{
			var s = F.CUtilities.NameAndCount("images", list);
			var lnks = new List<HyperLink>();
			foreach (var i in list)
			{
				var width = i.Fields["width"].AsLong;
				var height = i.Fields["height"].AsLong;
				var source = i.Fields["source"].AsString;
				var lnk = new HyperLink();
				lnk.Text = string.Concat(width, "x", height);
				lnk.NavigateUrl = source;
				lnk.ToolTip = lnk.NavigateUrl;
				lnks.Add(lnk);
			}
			AddCell(tr, lnks);
			return new List<CNodeBasic>(0);
		}



		if (list.Count == 1)
			return AddCell_CompositeItem(tr, f);
		AddCell(tr, F.CUtilities.NameAndCount(f.Tag.TagName, list));
		return list;
	}

	private TableCell AddCell_System(TableRow tr, CField f, bool highlight)
	{
		if (f is CFieldDate)
			return AddCell_Date(tr, f);

		var td = AddCell(tr, f.AsString);
		td.Font.Bold = highlight;


		return td;
	}
	private TableCell AddCell_Date(TableRow tr, CField f)
	{
		var df = (CFieldDate)f;
		var d = df.Date;

		var td = AddCell(tr, F.CUtilities.Timespan(d));
		td.ToolTip = F.CUtilities.LongDateTime(d);
		return td;
	}


	private void AddRow(Table tbl, CDiff i)
    {
        var tr = AddRow(tbl);

        AddCell(tr, i.Path).Font.Bold=true;
        AddCell(tr, i.Before.AsString);
        AddCell(tr, i.After.AsString);
    }
    private TableRow AddRow(Table tbl, bool? highlight = null)
    {
        var tr = new TableRow();
        tbl.Rows.Add(tr);

        if (null == highlight)
            highlight = tbl.Rows.Count % 2 == 1;
        if (highlight.Value)
            tr.Style.Add("background", "#eee");
        return tr;
    }
    private TableCell AddCell(TableRow tr, string s)
    {
        var td = new TableCell();
        tr.Cells.Add(td);
        td.Text = s;
        if (s.Length > 50)
        {
            td.ToolTip = td.Text;
            td.Text = Framework.CUtilities.Truncate(td.Text, 50);
        }
        td.Style.Add("border", "solid 1px #ddd");
        td.Style.Add("padding", "1px 3px");
        return td;
	}
	private TableCell AddCell(TableRow tr, List<HyperLink> s)
	{
		var td = new TableCell();
		tr.Cells.Add(td);
		foreach (var i in s)
		{
			if (0 != td.Controls.Count)
			{
				var lit = new Literal();
				lit.Text = ", ";
				td.Controls.Add(lit);
			}
			td.Controls.Add(i);
		}
		td.Style.Add("border", "solid 1px #ddd");
		td.Style.Add("padding", "1px 3px");
		return td;
	}
	private TableCell AddCell(TableRow tr, List<string> s)
	{
		var td = new TableCell();
		tr.Cells.Add(td);
		td.Text = F.CUtilities.ListToString(s,"<br/>");
		td.Style.Add("border", "solid 1px #ddd");
		td.Style.Add("padding", "1px 3px");
		return td;
	}
	private TableCell AddCellH(TableRow tr, string s)
    {
        var td = new TableHeaderCell();
        tr.Cells.Add(td);
        td.Text = s;
        return td;
    }
}